/*
 * Database.java
 */

package nxtgeninventorysystem.Model;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * The Database class provides global access to the database. It provides
 * general database functionalities such as querying, updating and connecting
 * to the database. It also contains database handlers for specific entities,
 * which can also be accessed globally.
 * @author Seraph Softworks
 */
public abstract class Database {

    //attributes
    public static final DatabaseItemHandler item = new DatabaseItemHandler();
    public static final DatabasePersonHandler person = new DatabasePersonHandler();
    public static final DatabaseTransactionHandler transaction = new DatabaseTransactionHandler();

    private static final String driver_import = "com.mysql.jdbc.Driver";
    private static final String driver_name = "jdbc:mysql://";
    private static final String settings_filename = "db.config";

    private static String hostname = "localhost";
    private static String port = "3306";
    private static String database = "nxtgen_inventory";
    private static String username = "root";
    private static String password = "12345";

    private static Connection connection;

    //methods
    public static boolean loadConnectionOptions() {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(new File(settings_filename)));
            setHostname(reader.readLine().substring(11));
            setPort(reader.readLine().substring(7));
            setDatabase(reader.readLine().substring(11));
            setUsername(reader.readLine().substring(11));
            setPassword(reader.readLine().substring(11));
            reader.close();
            return true;
        }
        catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
        setHostname("localhost");
        setPort("3306");
        setDatabase("nxtgen_inventory");
        setUsername("root");
        setPassword("12345");
        return false;
    }

    public static boolean saveConnectionOptions() {
        try {
            FileWriter writer = new FileWriter(settings_filename);
            writer.write("hostname = " + getHostname() + "\n");
            writer.write("port = " + getPort() + "\n");
            writer.write("database = " + getDatabase() + "\n");
            writer.write("username = " + getUsername() + "\n");
            writer.write("password = " + getPassword() + "\n");
            writer.close();
            return true;
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public static boolean connectToDatabase() {
        try {
            //Connect to the driver
            Class.forName(driver_import);
            String url = driver_name + getHostname() + ":" + getPort() + "/" + getDatabase();
            //acquires database connection
            connection = DriverManager.getConnection(url, getUsername(), getPassword());
            return true;
        }
        catch(SQLException ex){
            ex.printStackTrace();
        }
        catch(ClassNotFoundException ex){
            ex.printStackTrace();
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        connection = null;
        return false;
    }

    public static boolean executeUpdate(String statement) {
        try {
            PreparedStatement pstmt =
                    connection.prepareStatement(statement);
            pstmt.executeUpdate();
            return true;
        }
        catch(SQLException ex){
            ex.printStackTrace();
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public static boolean executeBatch(String[] batch) {
        try {
            PreparedStatement pstmt =
                    connection.prepareStatement("");
            for(int i = 0 ; i < batch.length ; i++) {
                pstmt.addBatch(batch[i]);
            }
            pstmt.executeBatch();
            return true;
        }
        catch(SQLException ex){
            ex.printStackTrace();
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public static ResultSet executeQuery(String statement) {
        try {
            PreparedStatement pstmt =
                    connection.prepareStatement(statement);
            return pstmt.executeQuery();
        }
        catch(SQLException ex){
            ex.printStackTrace();
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * @return the hostname
     */
    public static String getHostname() {
        return hostname;
    }

    /**
     * @param aHostname the hostname to set
     */
    public static void setHostname(String aHostname) {
        hostname = aHostname;
    }

    /**
     * @return the port
     */
    public static String getPort() {
        return port;
    }

    /**
     * @param aPort the port to set
     */
    public static void setPort(String aPort) {
        port = aPort;
    }

    /**
     * @return the database
     */
    public static String getDatabase() {
        return database;
    }

    /**
     * @param aDatabase the database to set
     */
    public static void setDatabase(String aDatabase) {
        database = aDatabase;
    }

    /**
     * @return the username
     */
    public static String getUsername() {
        return username;
    }

    /**
     * @param aUsername the username to set
     */
    public static void setUsername(String aUsername) {
        username = aUsername;
    }

    /**
     * @return the password
     */
    public static String getPassword() {
        return password;
    }

    /**
     * @param aPassword the password to set
     */
    public static void setPassword(String aPassword) {
        password = aPassword;
    }

    public static boolean isConnected() {
        try {
            if (connection == null) {
                return false;
            }
            else if (connection.isClosed()) {
                return false;
            }
            else if (!connection.isValid(5000)) {
                return false;
            }
            else {
                return true;
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
            Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

}
